package org.wdcode.common.nio;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;


import org.wdcode.common.constants.ArrayConstants;
import org.wdcode.common.constants.EncodingConstants;

import org.wdcode.common.log.WdLogs;
import org.wdcode.common.params.WdCommonParams;
import org.wdcode.common.tools.Arrays;
import org.wdcode.common.util.StringUtil;
import org.wdcode.common.util.CloseUtil;

/**
 * 关于NIO操作
 * @author WD
 * @since JDK6
 * @version 1.0 2009-04-21
 */
public final class StreamChannel {
	/**
	 * 读取InputStream内容成为字符串
	 * @param in 输入流
	 * @return 读取的字符串 失败返回""
	 */
	public final static String readString(InputStream in) {
		return readString(in, EncodingConstants.UTF_8);
	}

	/**
	 * 读取InputStream内容成为字符串
	 * @param in 输入流
	 * @param charsetName 编码格式
	 * @return 读取的字符串 失败返回""
	 */
	public final static String readString(InputStream in, String charsetName) {
		return StringUtil.toString(read(in), charsetName);
	}

	/**
	 * 读取出输入流的所有字节
	 * @param in 输入流
	 * @return 字节数组
	 */
	public final static byte[] read(InputStream in) {
		// 创建结果字节数组
		byte[] result = ArrayConstants.BYTES_EMPTY;
		// 声明ReadableByteChannel
		ReadableByteChannel rbc = null;
		try {
			// 创建ReadableByteChannel
			rbc = Channels.newChannel(in);
			// 获得一个ByteBuffer
			ByteBuffer buffer = ByteBuffer.allocate(WdCommonParams.getIoBufferSize());
			// 声明保存读取字符数量
			int num = 0;
			// 循环读取
			while ((num = rbc.read(buffer)) > 0) {
				// 添加
				result = Arrays.add(result, buffer.hasArray() ? buffer.array() : ArrayConstants.BYTES_EMPTY, num);
			}
		} catch (IOException e) {
			WdLogs.error(e);
		} finally {
			// 关闭资源
			CloseUtil.close(rbc, in);
		}
		// 返回字节数组
		return result;
	}

	/**
	 * 把text写入到os中
	 * @param out 输出流
	 * @param text 输入的字符串
	 * @return true false
	 */
	public final static boolean writeString(OutputStream out, String text) {
		return write(out, StringUtil.toBytes(text));
	}

	/**
	 * 把text写入到os中
	 * @param out 输出流
	 * @param text 输入的字符串
	 * @param charsetName 编码格式
	 * @return true false
	 */
	public final static boolean writeString(OutputStream out, String text, String charsetName) {
		return write(out, StringUtil.toBytes(text, charsetName));
	}

	/**
	 * 把字节数组写入到out中
	 * @param out 输出流
	 * @param b 字节数组
	 * @return true false
	 */
	public final static boolean write(OutputStream out, byte[] b) {
		return write(out, new ByteArrayInputStream(b));
	}

	/**
	 * 把text写入到os中
	 * @param out 输出流
	 * @param in 输入流
	 * @return true false
	 * @throws CustomException 写失败
	 */
	public final static boolean write(OutputStream out, InputStream in) {
		// 声明WritableByteChannel
		WritableByteChannel wbc = null;
		// 声明ReadableByteChannel
		ReadableByteChannel rbc = null;
		try {
			// 获得WritableByteChannel
			wbc = Channels.newChannel(out);
			// 创建ReadableByteChannel
			rbc = Channels.newChannel(in);
			// 获得一个
			ByteBuffer buffer = ByteBuffer.allocate(WdCommonParams.getIoBufferSize());
			// 声明保存读取字符数量
			int num = 0;

			// 循环读写
			while ((num = rbc.read(buffer)) > 0) {
				// 写文件
				wbc.write(buffer.hasArray() ? ByteBuffer.wrap(buffer.array(), 0, num) : ByteBuffer.wrap(ArrayConstants.BYTES_EMPTY));
				// 清空缓存
				buffer.clear();
			}
			// 返回成功
			return true;
		} catch (IOException e) {
			// 包装异常
			WdLogs.error(e);
		} finally {
			// 关闭资源
			CloseUtil.close(wbc, rbc, out, in);
		}
		// 返回失败
		return false;
	}

	/*
	 * 私有构造
	 */
	private StreamChannel() {}
}
